package com.qcdp.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qcdp.dto.Result;
import com.qcdp.entity.SeckillVoucher;
import com.qcdp.entity.VoucherOrder;
import com.qcdp.mapper.VoucherOrderMapper;
import com.qcdp.service.ISeckillVoucherService;
import com.qcdp.service.IVoucherOrderService;
import com.qcdp.utils.RedisIdWork;
import com.qcdp.utils.UserHolder;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author libo
 * @since 2022-05-22
 */
@Service
public class VoucherOrderServiceImpl extends ServiceImpl<VoucherOrderMapper, VoucherOrder> implements IVoucherOrderService {

    @Autowired
    ISeckillVoucherService seckillVoucherService;
    @Autowired
    RedisIdWork redisIdWork;

    @Autowired
    IVoucherOrderService voucherOrderService;

    @Autowired
    RedissonClient  redissonClient;

    //秒杀的方法
    @Override
    public Result seckillVoucher(Long voucherId) {
        SeckillVoucher seckillVoucher  = seckillVoucherService.getById(voucherId);
        //1.判断秒杀是否开始
        if(seckillVoucher.getBeginTime().isAfter(LocalDateTime.now())){
            return Result.fail("抢购尚未开始");
        }
        //2.判断秒杀是否结束
        if(seckillVoucher.getEndTime().isBefore(LocalDateTime.now())){
            return Result.fail("抢购已经结束了！");
        }
        //3.判断库存是否充足
        if(seckillVoucher.getStock() < 1){
            return Result.fail("优惠券已售空！");
        }

        //4.判断用户是否重复下单(把一个字符串当道常量池中)
        return createVoucherOrder(voucherId);

    }
    //alt+ctrl+m  选中代码之后快速封装
    @Transactional
    public Result createVoucherOrder(Long voucherId) {
        Long userId = UserHolder.getUser().getId();
        //使用用户的iD来所谓锁的关键字，这样就能保证一个用户只能有一个线程来执行，多个用户可以有多个线程来执行。能提高我们系统并发能力

        RLock lock = redissonClient.getLock("order:" + userId);

        boolean isLock = lock.tryLock();
        if(!isLock){
            return Result.fail("优惠券不可重复购买！");
        }

        try {
            Integer count = this.lambdaQuery().eq(VoucherOrder::getUserId, userId)
                    .eq(VoucherOrder::getVoucherId, voucherId)
                    .count();
            //说明用户已经下过单了
            if(count > 0){
                return Result.fail("优惠券不可重复购买！");
            }


            //5.开始抢购了
            boolean success = seckillVoucherService.update()
                    .eq("voucher_id", voucherId)
                    .gt("stock",0)//只要是库存大于0我就可以下单
                    .setSql(" stock = stock -1 ")
                    .update();// update tb_seckill_voucher set stock = stock -1  where voucher_id = 2

            if(!success){
                return  Result.fail("抢购失败！");
            }
            //6.创建订单
            VoucherOrder voucherOrder = new VoucherOrder();

            long id = redisIdWork.nextId("order");

            voucherOrder.setId(id);
            voucherOrder.setVoucherId(voucherId);
            voucherOrder.setUserId(userId);

            voucherOrderService.save(voucherOrder);

            return Result.ok(id);
        } finally {
            //释放锁
            lock.unlock();
        }

    }
}
